BOJ_2096_내려가기
별표는 현재 위치이고, 그 아랫 줄의 파란 동그라미는 원룡이가 다음 줄로 내려갈 수 있는 위치이며, 빨간 가위표는 원룡이가 내려갈 수 없는 위치가 된다.
슬라이딩 윈도우(Sliding Window) 알고리즘과 DP를 이용하여 풀 수 있는 문제
메모리 제한이 없었다면 입력값을 모두 받아서 int[][][] dp 를 정의하고 DP를 수행할 수 있었겠지만,
제한 메모리가 4MB 밖에 안 되기 때문에 최대 100000*100000
배열을 저장할 수 없다
따라서 슬라이딩 윈도우 기법을 차용하여 int[] 타입의 dp를 정의하고 이를 연속적으로 초기화하면 된다
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
int[] maxDp = new int[3];
int[] minDp = new int[3];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
int x1 = Integer.parseInt(st.nextToken());
int x2 = Integer.parseInt(st.nextToken());
int x3 = Integer.parseInt(st.nextToken());
if (i == 0) {
maxDp[0] = minDp[0] = x1;
maxDp[1] = minDp[1] = x2;
maxDp[2] = minDp[2] = x3;
} else {
// 최댓값을 구하는 dp 배열
int beforeMaxDp_0 = maxDp[0], beforeMaxDp_2 = maxDp[2];
maxDp[0] = Math.max(maxDp[0], maxDp[1]) + x1;
maxDp[2] = Math.max(maxDp[1], maxDp[2]) + x3;
maxDp[1] = Math.max(Math.max(beforeMaxDp_0, maxDp[1]), beforeMaxDp_2) + x2;
// 최솟값을 구하는 dp 배열
int beforeMinDp_0 = minDp[0], beforeMinDp_2 = minDp[2];
minDp[0] = Math.min(minDp[0], minDp[1]) + x1;
minDp[2] = Math.min(minDp[1], minDp[2]) + x3;
minDp[1] = Math.min(Math.min(beforeMinDp_0, minDp[1]), beforeMinDp_2) + x2;
}
}
bw.write(Math.max(maxDp[0], Math.max(maxDp[1], maxDp[2])) + " ");
bw.write(Math.min(minDp[0], Math.min(minDp[1], minDp[2])) + "\n");
bw.flush();
bw.close();
br.close();